package rs.mbs2.epics.server.servlet;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;

import rs.mbs2.epics.server.entity.ProfileImage;
import rs.mbs2.epics.server.entity.User;
import rs.mbs2.epics.server.servlet.util.ImageUtil;
import rs.mbs2.epics.server.servlet.util.Parse;
import rs.mbs2.epics.server.servlet.util.Validation;
import rs.mbs2.epics.server.session.dao.localinterface.ProfileImageDaoLocal;
import rs.mbs2.epics.server.session.dao.localinterface.UserDaoLocal;

@SuppressWarnings("serial")
public class RegistrationController extends HttpServlet {

	private static Logger log = Logger.getLogger(RegistrationController.class);
	private static final String folderFilesOnServerName = "Files";
	private static final String thumbnailsFolderOnServerName = "thumbnails";
	
	@EJB
	private UserDaoLocal userDao;
	
	@EJB
	private ProfileImageDaoLocal profileImageDao;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		try {

			String emailAddress = null;
			String password = null;
			String firstname = null;
			String lastname = null;
			String gender = null;
			String dateOfBirthString = null;
			Date dateOfBirth = null;
			boolean emailNotifications = false;

			@SuppressWarnings("unchecked")
			List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);

			for (FileItem item : items) {
				if (item.isFormField()) {

					boolean isValid = true;

					if(item.getFieldName().equals("emailAddress")) {
						emailAddress = item.getString();
						isValid = Validation.validateString(emailAddress);
						isValid = Validation.validateEmailAddress(emailAddress, userDao);
					} else if(item.getFieldName().equals("password")) {
						password = item.getString();
						isValid = Validation.validateString(password);
					} else if(item.getFieldName().equals("firstname")) {
						firstname = item.getString();
						isValid = Validation.validateString(firstname);
					} else if(item.getFieldName().equals("lastname")) {
						lastname = item.getString();
						isValid = Validation.validateString(lastname);
					} else if(item.getFieldName().equals("gender")) {
						gender = item.getString();
						isValid = Validation.validateString(gender);
					} else if(item.getFieldName().equals("dateOfBirth")) {
						dateOfBirthString = item.getString();
						isValid = Validation.validateString(dateOfBirthString);
						if(isValid) {
							dateOfBirth = Parse.parseDate(dateOfBirthString);
						}
					} else if(item.getFieldName().equals("emailNotifications")) {
						emailNotifications = item.getString() != null;	// ako nije štiklirano biće true
					} else if(item.getFieldName().equals("")) {

					}

					if(!isValid) {
						log.error(new Date() + "Greška pri validaciji parametara.");
						response.sendRedirect(response.encodeRedirectURL("./register.jsp"));
					}

				} 
			}

			// prvo se napravi user bez profilne slike, da bi se dobio njegov id koji će služiti za korisnikovog foldera
			User newUser = new User(emailAddress, password, firstname, lastname, gender, dateOfBirth, emailNotifications, null);
			userDao.persist(newUser);

			for (FileItem item : items) {
				if (!item.isFormField()) {	// fajl (slika)

					String folderName = item.getFieldName();	// profileImage
					String fileName = item.getName();

					if(!fileName.equals("")) {	// ako je odabrana neka slika za upload

						int newUserId = newUser.getId();
						// /Files/1
						String userFolderPath = getServletContext().getRealPath("") + "/" + folderFilesOnServerName + "/" +  newUserId;

						// kreira direktorijume: /Files/1/profileImage/
						// vrati putanju:  /Files/1/profileImage/imeSlike.jpg
						String filePath = ImageUtil.createImagePaths(userFolderPath, folderName, fileName);

						File fileToUpload = new File(filePath);		// kreira fajl: /Files/1/profileImage/imeSlike.jpg
						item.write(fileToUpload);

						//BufferedImage sourceImage = ImageIO.read(new File(filePath));
						BufferedImage image = ImageIO.read(fileToUpload);
						BufferedImage thumbnail = ImageUtil.getThumbnail(filePath, image);
						// kreira direktorijume: /Files/1/profileImage/thumbnails/
						// vrati putanju: /Files/1/profileImage/thumbnails/imeSlike.jpg
						String thumbnailFilePath = ImageUtil.getThumbnailPath(userFolderPath, folderName, fileName);

						File thumbnailImageFile = new File(thumbnailFilePath);	// kreira fajl: /Files/1/profileImage/thumbnails/imeSlike.jpg
						ImageIO.write(thumbnail, "jpg", thumbnailImageFile);

						int width = image.getWidth();
						int height = image.getHeight();
						byte[] imageBytes = ((DataBufferByte) image.getData().getDataBuffer()).getData();
						Long size = new Long(imageBytes.length);
						String relativeFilePath = folderFilesOnServerName + "/" + newUserId + "/" + folderName + "/" + fileName;
						String relativeThumbnailPath = folderFilesOnServerName + "/" + newUserId + "/" + folderName + "/" + thumbnailsFolderOnServerName + "/" + fileName;
						ProfileImage profileImage = new ProfileImage(relativeFilePath, relativeThumbnailPath, width, height, size, new Date(), newUser);
						
						profileImageDao.persist(profileImage);
						newUser.setProfileImage(profileImage);
						userDao.merge(newUser);
						
					} else {
						
						String relativeFilePath = folderFilesOnServerName + "/" + "default.jpg";
						String relativeThumbnailPath = folderFilesOnServerName + "/" + "default_thumbnail.jpg";
						ProfileImage defaultProfilePicture = new ProfileImage(relativeFilePath, relativeThumbnailPath, new Integer(284), new Integer(178), new Long(1052), new Date(), newUser);
						profileImageDao.persist(defaultProfilePicture);
						newUser.setProfileImage(defaultProfilePicture);
						userDao.merge(newUser);
						
					}
					

					break;	// ocekuje se samo jedna slika, nema potrebe da se dalje prolazi kroz polja na formi.
				}
			}

			request.getSession().setAttribute("user", newUser);	// ulogovan je odmah
			getServletContext().getRequestDispatcher("/home.jsp").forward(request, response);			
			
		} catch (IOException e) {
			log.error((new Date()).toString() + e);
			e.printStackTrace();
		} catch (FileUploadException e) {
			log.error((new Date()).toString() + e);
			e.printStackTrace();
		} catch (ParseException e) {
			log.error((new Date()).toString() + e);
			e.printStackTrace();
		} catch (Exception e) {
			log.error((new Date()).toString() + e);
			e.printStackTrace();
		}


	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
